home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianTextFiles.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  7KB  |  341 lines

  1. /*ScianTextFiles.c
  2.   Eric Pepke
  3.   24 February 1993
  4.  
  5.   Stuff for reading text files from SciAn
  6. */
  7.  
  8. #include "Scian.h"
  9. #include "ScianTypes.h"
  10. #include "ScianIDs.h"
  11. #include "ScianTextFiles.h"
  12.  
  13. TextFilePtr allTextFiles = 0;
  14.  
  15. void InitTextFiles()
  16. /*Initialize the text file system*/
  17. {
  18.     allTextFiles = 0;
  19. }
  20.  
  21. #ifdef PROTO
  22. TextFilePtr OpenTextFile(char *name, TextFlagsTyp flags)
  23. #else
  24. TextFilePtr OpenTextFile(name, flags)
  25. char *name;
  26. TextFlagsTyp flags;
  27. #endif
  28. /*Opens a text file with name and flags.  Returns it, or returns null.*/
  29. {
  30.     FILE *filePtr;
  31.     TextFilePtr retVal;
  32.  
  33.     if (flags & TF_READ)
  34.     {
  35.     filePtr = fopen(name, "r");
  36.     }
  37.     else
  38.     {
  39.     return NULL;
  40.     }
  41.     if (filePtr)
  42.     {
  43.     /*Create a text file structure*/
  44.     retVal = newp(TextFile);
  45.     if (!retVal)
  46.     {
  47.         OMErr();
  48.         return NULL;
  49.     }
  50.  
  51.     /*Fill in stuff*/
  52.     retVal -> flags = flags;
  53.     retVal -> eof = 0;
  54.     retVal -> lineNum = 0;
  55.     retVal -> nAlloc = TEXTLINEALLOCCHUNK;
  56.     retVal -> curLine = Alloc(TEXTLINEALLOCCHUNK);
  57.     if (!retVal -> curLine)
  58.     {
  59.         Free(retVal);
  60.         return NULL;
  61.     }
  62.     retVal -> name = Alloc(strlen(name) + 1);
  63.     if (!retVal -> name)
  64.     {
  65.         Free(retVal -> curLine);
  66.         OMErr();
  67.         return NULL;
  68.     }
  69.     strcpy(retVal -> name, name);
  70.     retVal -> filePtr = filePtr;
  71.     retVal -> lineNum = 0;
  72.  
  73.     /*Link to all and return*/
  74.     retVal -> next = allTextFiles;
  75.     allTextFiles = retVal;
  76.     return retVal;
  77.     }
  78.     else
  79.     {
  80.     return NULL;
  81.     }
  82. }
  83.  
  84. #ifdef PROTO
  85. void CloseTextFile(TextFilePtr textFile)
  86. #else
  87. void CloseTextFile(textFile)
  88. TextFilePtr textFile;
  89. #endif
  90. /*Closes a text file*/
  91. {
  92.     TextFilePtr *runner;
  93.  
  94.     fclose(textFile -> filePtr);
  95.     Free(textFile -> name);
  96.     Free(textFile -> curLine);
  97.     runner = &allTextFiles;
  98.     while (*runner)
  99.     {
  100.     if (*runner == textFile)
  101.     {
  102.         (*runner) = (*runner) -> next;
  103.     }
  104.     else
  105.     {
  106.         runner = &((*runner) -> next);
  107.     }
  108.     }
  109.     Free(textFile);
  110. }
  111.  
  112. #define MAXERROREND    75
  113. #define ERRORPREVIOUS    30
  114.  
  115. #ifdef PROTO
  116. void CurLineError(TextFilePtr textFile, char *message, char *beginning, char *end)
  117. #else
  118. void CurLineError(textFile, message, beginning, end)
  119. TextFilePtr textFile;
  120. char *message;
  121. char *beginning;
  122. char *end;
  123. #endif
  124. /*Prints to standard error an error message about reading file textFile.
  125.   message is a message to print or NULL.  message should not contain 
  126.     newline at the end.
  127.   beginning and end may point to the begin and end+1 of the portion of the
  128.   string where the error is, in which case the line or a portion of the
  129.   line will be printed, or they may be NULL*/
  130. {
  131.     fprintf(stderr, "Error in file '%s' line %d%c\n",
  132.     textFile -> name, textFile -> lineNum,
  133.     (message || (beginning && end)) ? ':' : '.');
  134.     if (beginning && end)
  135.     {
  136.     /*Determine a good place to begin and end*/
  137.     char *s;
  138.     int column;
  139.     column = 0;
  140.  
  141.     for (s = textFile -> curLine;
  142.         (*s) && (s < end) && (column < MAXERROREND);
  143.         ++s)
  144.     {
  145.         ++column;
  146.         if (*s == '\t') column = column - column % 8 + 8;
  147.     }
  148.     if (column < MAXERROREND)
  149.     {
  150.         /*Just print normally*/
  151.  
  152.         /*Print the line first*/
  153.         column = 0;
  154.         for (s = textFile -> curLine;
  155.         (*s) && (*s != '\n') && column < MAXERROREND;
  156.         ++s)
  157.         {
  158.         fputc(*s, stderr);
  159.         ++column;
  160.         if (*s == '\t') column = column - column % 8 + 8;
  161.         }
  162.         if (*s && (*s != '\n'))
  163.         {
  164.         /*Not really the end, continuation*/
  165.         fprintf(stderr, "...\n");
  166.         }
  167.         else
  168.         {
  169.         fprintf(stderr, "\n");
  170.         }
  171.  
  172.         /*Now print the stuff underneath*/
  173.  
  174.         column = 0;
  175.         for (s = textFile -> curLine;
  176.         (*s) && (s < beginning);
  177.         ++s)
  178.         {
  179.         fputc(*s == '\t' ? '\t' : ' ', stderr);
  180.         }
  181.  
  182.         for (;
  183.          (*s) && (s < end);
  184.          ++s)
  185.         {
  186.         fputc(*s == '\t' ? '\t' : '^', stderr);
  187.         }
  188.         fprintf(stderr, "\n");
  189.     }
  190.     else
  191.     {
  192.         /*Back off a little*/
  193.     }
  194.     }
  195.     if (message)
  196.     {
  197.     fprintf(stderr, "%s\n", message);
  198.     }
  199. }
  200.  
  201. /*States for reading in text file*/
  202. #define TFS_BOL        1    /*Beginning of line*/
  203. #define TFS_NORMAL    2    /*Normal*/
  204. #define TFS_MAYBECONT    3    /*May be a continuation*/
  205. #define TFS_ANOTHERLINE    4    /*Must read another line*/
  206.  
  207. #ifdef PROTO
  208. char *GetNextLine(TextFilePtr textFile)
  209. #else
  210. char *GetNextLine(textFile)
  211. TextFilePtr textFile;
  212. #endif
  213. /*Advances to the next line and gets it, or NULL if file closed or EOF or
  214.   error*/
  215. {
  216.     long nChars;
  217.     char *success;
  218.     int k;
  219.     int state;
  220.  
  221.     if (!(textFile -> flags | TF_READ)) return NULL;
  222.  
  223.     if (textFile -> eof) return NULL;
  224.  
  225.     for (;;)
  226.     {
  227.     state = TFS_BOL;
  228.  
  229.     nChars = 0;
  230.     do
  231.     {
  232.         /*Get a single line*/
  233.         success = fgets(tempStr, TEMPSTRSIZE, textFile -> filePtr);
  234.         if (!success && (state = TFS_BOL))
  235.         {
  236.         /*Must be an end of file*/
  237.         textFile -> eof = true;
  238.         break;
  239.         }
  240.         ++textFile -> lineNum;
  241.  
  242.         if (!success)
  243.         {
  244.         /*There must be nothing more in the line*/
  245.         break;
  246.         }
  247.  
  248.         /*It's OK, add it to what's there*/
  249.         for (k = 0; tempStr[k]; ++k)
  250.         {
  251.         if (nChars > (textFile -> nAlloc - 2))
  252.         {
  253.             /*Expand buffer*/
  254.             textFile -> nAlloc += TEXTLINEALLOCCHUNK;
  255.             textFile -> curLine = Realloc(textFile -> curLine, textFile -> nAlloc);
  256.             if (!(textFile -> curLine))
  257.             {
  258.             OMErr();
  259.             return NULL;
  260.             }
  261.         }
  262.         if (tempStr[k] == '\n')
  263.         {
  264.             /*End of line*/
  265.             if (state == TFS_MAYBECONT)
  266.             {
  267.             /*It's a continuation line.*/
  268.             --nChars;
  269.             state = TFS_ANOTHERLINE;
  270.             break;
  271.             }
  272.             else if (textFile -> flags & TF_INCLUDENL)
  273.             {
  274.             textFile -> curLine[nChars++] = '\n';
  275.             state = TFS_NORMAL;
  276.             }
  277.         }
  278.         else if ((textFile -> flags & TF_CONTINUATION) &&
  279.             (tempStr[k] == '\\'))
  280.         {
  281.             /*It might be a continuation line*/
  282.             textFile -> curLine[nChars++] = '\\';
  283.             state = TFS_MAYBECONT;
  284.         }
  285.         else
  286.         {
  287.             textFile -> curLine[nChars++] = tempStr[k];
  288.             state = TFS_NORMAL;
  289.         }
  290.         }
  291.     } while (state == TFS_ANOTHERLINE);
  292.  
  293.     /*Now the buffer has been filled.  Figure out what to do with it.*/
  294.     if (textFile -> eof)
  295.     {
  296.         /*End of file was hit.*/
  297.         return NULL;
  298.     }
  299.     textFile -> curLine[nChars] = 0;
  300.     if ((textFile -> flags & TF_HASHCOMMENTS) &&
  301.         (textFile -> curLine[0] == '#'))
  302.     {
  303.         /*This is a comment.  Don't do anything, just read another line*/
  304.     }
  305.     else
  306.     {
  307.         return textFile -> curLine;
  308.     }
  309.     }
  310. }
  311.  
  312. #ifdef PROTO
  313. char *GetCurLine(TextFilePtr textFile)
  314. #else
  315. char *GetCurLine(textFile)
  316. TextFilePtr textFile;
  317. #endif
  318. /*Gets the current line.  Returns NULL if file is closed or at EOF or error*/
  319. {
  320.     if (!(textFile -> flags | TF_READ)) return NULL;
  321.     if (textFile -> eof) return NULL;
  322.     if (textFile -> lineNum == 0)
  323.     {
  324.     return GetNextLine(textFile);
  325.     }
  326.     return (textFile -> curLine);
  327. }
  328.  
  329. void KillTextFiles()
  330. /*Kill the text file system*/
  331. {
  332.     TextFilePtr fileToClose;
  333.  
  334.     while (allTextFiles)
  335.     {
  336.     fileToClose = allTextFiles;
  337.     allTextFiles = allTextFiles -> next;
  338.     CloseTextFile(fileToClose);
  339.     }
  340. }
  341.